home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / dvips / prescan.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-01-05  |  6.9 KB  |  230 lines

  1. /*
  2.  *   This is the main routine for the first (prescanning) pass.
  3.  */
  4. #include "structures.h" /* The copyright notice in that file is included too! */
  5. /*
  6.  *   These are all the external routines it calls:
  7.  */
  8. extern void error() ;
  9. extern shalfword dvibyte() ;
  10. extern integer signedquad() ;
  11. extern int skipnop() ;
  12. extern void skipover() ;
  13. extern short scanpage() ;
  14. extern void skippage() ;
  15. /*
  16.  *   These are the globals it accesses.
  17.  */
  18. #ifdef DEBUG
  19. extern integer debug_flag;
  20. #endif  /* DEBUG */
  21. extern fontdesctype *fonthead ;
  22. extern real conv ;
  23. extern real alpha ;
  24. extern integer firstpage ;
  25. extern Boolean notfirst ;
  26. extern integer fontmem ;
  27. extern integer pagecount ;
  28. extern integer pagenum ;
  29. extern integer maxpages ;
  30. extern sectiontype *sections ;
  31. extern FILE *dvifile ;
  32. extern integer mag ;
  33. extern Boolean overridemag ;
  34. extern integer swmem ;
  35. extern int quiet ;
  36. extern int actualdpi ;
  37. extern Boolean reverse ;
  38. extern int totalpages ;
  39. /*
  40.  *   We declare the type malloc returns.
  41.  */
  42. char *malloc() ;
  43. /*
  44.  *   This routine handles the processing of the preamble in the dvi file.
  45.  */
  46. void
  47. readpreamble()
  48. {
  49.    register integer num, den;
  50.    register int i ;
  51.  
  52.    if (dvibyte()!=247) error("! Bad DVI file: first byte not preamble") ;
  53.    if (dvibyte()!=2) error("! Bad DVI file: id byte not 2") ;
  54.    num = signedquad() ;
  55.    den = signedquad() ;
  56.    if (overridemag) (void)signedquad() ;
  57.    else mag = signedquad() ;
  58.    conv = (real) num * DPI * (real) mag / ( den * 254000000.0 ) ; 
  59.    alpha = (((real)den / 7227.0) / 0x100000) * (25400000.0 / (real) num) ;
  60.    if (! quiet) {
  61.       (void)fprintf(stderr, "'") ;
  62.       for(i=dvibyte();i>0;i--) (void)putc(dvibyte(), stderr) ;
  63.       (void)fprintf(stderr, "'\n") ;
  64.    } else
  65.       skipover(dvibyte()) ;
  66. }
  67.  
  68. /*
  69.  *   Finally, here's our main prescan routine.
  70.  */
  71. void
  72. prescanpages()
  73. {
  74.    register int cmd ;
  75.    short ret ;
  76.    register integer thispageloc, thissecloc ;
  77.    register fontdesctype *f ;
  78.    register shalfword c ;
  79.  
  80.    readpreamble() ;
  81. /*
  82.  *   Now we look for the first page to process.  If we get to the end of
  83.  *   the file before the page, we complain (fatally).
  84.  *   Incidentally, we don't use the DVI file's bop backpointer to skip
  85.  *   over pages at high speed, because we want to look to for special
  86.  *   header that might be in skipped pages.
  87.  */
  88.    while (1) {
  89.       cmd = skipnop() ;
  90.       if (cmd==248)
  91.          error("! End of document before first specified page") ;
  92.       if (cmd!=139)
  93.          error("! Bad DVI file: expected bop") ;
  94.       thispageloc = ftell(dvifile) ; /* the location FOLLOWING the bop */
  95. #ifdef DEBUG
  96.       if (dd(D_PAGE))
  97. #ifdef SHORTINT
  98.       (void)fprintf(stderr,"bop at %ld\n", thispageloc) ;
  99. #else   /* ~SHORTINT */
  100.       (void)fprintf(stderr,"bop at %d\n", thispageloc) ;
  101. #endif  /* ~SHORTINT */
  102. #endif  /* DEBUG */
  103.       pagenum = signedquad() ;
  104.       if (notfirst && pagenum != firstpage)
  105.          skippage() ;
  106.       else
  107.          break ;
  108.    }
  109. /*
  110.  *   Here we scan for each of the sections.  First we initialize some of
  111.  *   the variables we need.
  112.  */
  113.    while (maxpages > 0 && cmd != 248) {
  114.       for (f=fonthead; f; f=f->next) {
  115.          f->psname = 0 ;
  116.          if (f->loaded==1)
  117.             for (c=255; c>=0; c--)
  118.                f->chardesc[c].flags &= (EXISTS | REPACKED) ;
  119.       }
  120.       fontmem = swmem - OVERCOST ;
  121.       if (fontmem <= 1000)
  122.          error("! Too little VM in printer") ;
  123.  
  124. /*   The section begins at the bop command just before thispageloc (which may
  125.  *   be a page that was aborted because the previous section overflowed memory).
  126.  */
  127.       pagecount = 0 ;
  128.       (void)fseek(dvifile, (long)thispageloc+44, 0) ;
  129.       thissecloc = thispageloc ;
  130. /*
  131.  *   Now we have the loop that actually scans the pages.  The scanpage routine
  132.  *   returns 1 if the page scans okay; it returns 2 if the memory ran out
  133.  *   before any pages were completed (in which case we'll try to carry on
  134.  *   and hope for the best); it returns 0 if a page was aborted for lack
  135.  *   of memory. After each page, we mark the characters seen on that page
  136.  *   as seen for this section so that they will be downloaded.
  137.  */
  138.       while (maxpages>0 && (ret=scanpage())) {
  139.          if (reverse)
  140.             thissecloc = thispageloc ;
  141.          pagecount++ ;
  142.          maxpages-- ;
  143.          for (f=fonthead; f; f=f->next)
  144.             if (f->loaded==1)
  145.                for (c=255; c>=0; c--)
  146.                   if (f->chardesc[c].flags & THISPAGE)
  147.                      f->chardesc[c].flags = PREVPAGE |
  148.                (f->chardesc[c].flags & (EXISTS | REPACKED)) ;
  149.          cmd=skipnop() ;
  150.          if (cmd==248) break ;
  151.          if (cmd!=139)
  152.             error("! Bad DVI file: expected bop") ;
  153.          thispageloc = ftell(dvifile) ;
  154. #ifdef DEBUG
  155.          if (dd(D_PAGE))
  156. #ifdef SHORTINT
  157.          (void)fprintf(stderr,"bop at %ld\n", thispageloc) ;
  158. #else   /* ~SHORTINT */
  159.          (void)fprintf(stderr,"bop at %d\n", thispageloc) ;
  160. #endif  /* ~SHORTINT */
  161. #endif  /* DEBUG */
  162.          pagenum = signedquad() ;
  163.          skipover(40) ;
  164.          if (ret==2) break ;
  165.       }
  166. /*
  167.  *   Now we have reached the end of a section for some reason.
  168.  *   If there are any pages, we save the pagecount, section location,
  169.  *   and continue.
  170.  */
  171.       if (pagecount>0) {
  172.          register int fc = 0 ;
  173.          register sectiontype *sp ;
  174.          register charusetype *cp ;
  175.  
  176.          totalpages += pagecount ;
  177.          for (f=fonthead; f; f=f->next)
  178.             if (f->loaded==1)
  179.                fc++ ;
  180.          sp = (sectiontype *)malloc((unsigned int)(sizeof(sectiontype) + 
  181.             fc * sizeof(charusetype) + sizeof(fontdesctype *))) ;
  182.          if (sp==NULL)
  183.             error("! out of memory") ;
  184.          sp->bos = thissecloc ;
  185.          if (reverse) {
  186.             sp->next = sections ;
  187.             sections = sp ;
  188.          } else {
  189.             register sectiontype *p ;
  190.  
  191.             sp->next = NULL ;
  192.             if (sections == NULL)
  193.                sections = sp ;
  194.             else {
  195.                for (p=sections; p->next != NULL; p = p->next) ;
  196.                p->next = sp ;
  197.             }
  198.          }
  199.          sp->numpages = pagecount ;
  200. #ifdef DEBUG
  201.         if (dd(D_PAGE))
  202. #ifdef SHORTINT
  203.          (void)fprintf(stderr,"Have a section: %ld pages at %ld fontmem %ld\n", 
  204. #else   /* ~SHORTINT */
  205.          (void)fprintf(stderr,"Have a section: %d pages at %d fontmem %d\n", 
  206. #endif  /* ~SHORTINT */
  207.              pagecount, thissecloc, fontmem) ;
  208. #endif  /* DEBUG */
  209.          cp = (charusetype *) (sp + 1) ;
  210.          for (f=fonthead; f; f=f->next)
  211.             if (f->loaded==1 && f->psname) {
  212.                register halfword b, bit ;
  213.  
  214.                cp->fd = f ;
  215.                c = 0 ;
  216.                for (b=0; b<16; b++) {
  217.                   cp->bitmap[b] = 0 ;
  218.                   for (bit=32768; bit!=0; bit>>=1) {
  219.                      if (f->chardesc[c].flags & PREVPAGE)
  220.                         cp->bitmap[b] |= bit ;
  221.                   c++ ;
  222.                   }
  223.                }
  224.                cp++ ;
  225.             }
  226.          cp->fd = NULL ;
  227.       }
  228.    }
  229. }
  230.